﻿using System;
using DO.DreamOnTrader.Quote;
namespace DO.DreamOnTrader.Indicator
{
	/// <summary>
	/// 傳入報價，依HuringMin產出需要的分k報價
	/// </summary>
	public class KBarComputer
	{
		public KBarComputer(int _huringMin)
		{
			HuringMin = _huringMin;
		}
		
		#region ========變數

		/// <summary>
		/// K開盤價
		/// </summary>
		float OpenPrice;

		/// <summary>
		/// K最高價
		/// </summary>
		float HPrice;

		/// <summary>
		/// K最低價
		/// </summary>
		float LPrice;

		/// <summary>
		/// k收盤價
		/// </summary>
		float ClosePrice;

		/// <summary>
		/// k成交量
		/// </summary>
		uint Vol;

		/// <summary>
		/// k結束時間
		/// </summary>
		DateTime Ktime = DateTime.MinValue;

		#endregion

		/// <summary>
		/// 傳入報價
		/// </summary>
		/// <param name="tick"></param>
		public void compute(Tick tick)
		{
			if (tick.TradeTime > Ktime)
			{
				if (Ktime != DateTime.MinValue)
				{
					BuildingKBar(new KBar(OpenPrice, HPrice, LPrice, ClosePrice, Vol, Ktime));
				}

				//新的kbar
				OpenPrice = tick.Price;
				HPrice = tick.Price;
				LPrice = tick.Price;
				ClosePrice = tick.Price;
				Vol = tick.Qty;
				Ktime = setKtime(tick.TradeTime);

			}
			else
			{
				if (tick.Price > HPrice) HPrice = tick.Price;
				if (tick.Price < LPrice) LPrice = tick.Price;
				ClosePrice = tick.Price;
				Vol += tick.Qty;
			}
		}

		/// <summary>
		/// 傳入報價
		/// </summary>
		/// <param name="kbar"></param>
		public void compute(KBar kb)
		{
			if (kb.Ktime > Ktime)
			{
				if (Ktime != DateTime.MinValue)
				{
					BuildingKBar(new KBar(OpenPrice, HPrice, LPrice, ClosePrice, Vol, Ktime));
				}

				//新的kbar
				OpenPrice = kb.OpenPrice;
				HPrice = kb.HPrice;
				LPrice = kb.LPrice;
				ClosePrice = kb.ClosePrice;
				Vol = kb.Vol;
				Ktime = setKtime(kb.Ktime);

			}
			else
			{
				if (kb.HPrice > HPrice) HPrice = kb.HPrice;
				if (kb.LPrice < LPrice) LPrice = kb.LPrice;
				ClosePrice = kb.ClosePrice;
				Vol += kb.Vol;
			}
		}

		/// <summary>
		/// 求得此k線的時間
		/// </summary>
		/// <param name="ne"></param>
		/// <returns></returns>
		private DateTime setKtime(DateTime ne)
		{
			DateTime kt = (this.Ktime == DateTime.MinValue) ? new DateTime(ne.Year, ne.Month, ne.Day, 8, 45, 0) : this.Ktime;

			if (ne == kt)
			{
				return kt.AddMinutes(HuringMin);
			}
			while (kt < ne)
			{
				kt = kt.AddMinutes(HuringMin);
			}
			return kt;
		}

		/// <summary>
		/// 幾分k線,key值
		/// </summary>
		public int HuringMin { get; private set; }

		public event BuildingKBarEventHandler BuildingKBar;

	}
}
